چرا داده تکراری مسائل واقعی ایجاد میکند
حتی پس از شناسایی درست موجودیتها، ویژگیها، و روابط که پیشتر در این مجموعه بحث شد، ساختار داخلی یک جدول همچنان میتواند اجازه دهد همان قطعه اطلاعات در چند مکان ذخیره شود، که سه نوع خاص از مسائل به نام Anomalies (ناهنجاریها) ایجاد میکند.
جدول مسئلهساز که چند مفهوم را با هم مخلوط میکند:
| order_id | product_name | customer_name | customer_email |
|----------|---------------|----------------|-------------------|
| 1 | Widget | Alice Smith | [email protected] |
| 2 | Gadget | Alice Smith | [email protected] |
ناهنجاری بهروزرسانی: تغییر ایمیل آلیس نیازمند
بهروزرسانی آن در هر ردیفی است که او ظاهر میشود
ناهنجاری درج: نمیتوان اطلاعات یک مشتری جدید را
ثبت کرد تا اولین سفارشش را ثبت کند
ناهنجاری حذف: حذف تنها سفارش آلیس
تصادفاً اطلاعات تماسش را کاملاً پاک میکندNormalization (نرمالسازی) یک مجموعه رسمی از قوانین است، سازماندهیشده در مراحل تدریجی به نام Normal Forms (فرمهای نرمال)، که بهطور خاص برای بازساختاردهی جداول طراحی شده طوریکه این ناهنجاریها از نظر ساختاری غیرممکن شوند.
فرم نرمال اول (1NF): فقط مقادیر اتمی
یک جدول First Normal Form (فرم نرمال اول) را برآورده میکند وقتی هر ستون یک مقدار واحد و اتمی نگه دارد — بدون گروههای تکراری و بدون چند مقدار فشردهشده در یک فیلد.
1NF را نقض میکند:
| book_id | title | authors |
|---------|------------|---------------------------|
| 1 | Deep Work | Cal Newport |
| 2 | Sapiens | Yuval Harari, Dan Editor |
1NF را برآورده میکند (با استفاده از رویکرد جدول اتصال
که پیشتر در این مجموعه برای رابطه چندبهچند
بین کتابها و نویسندهها بحث شد):
books: book_id، title
authors: author_id، name
book_authors: book_id، author_idاین مستقیماً به مسئله ویژگی چندمقداری که پیشتر در این مجموعه درباره طراحی موجودیت بحث شد متصل میشود: هر تلاشی برای ذخیره چند مقدار در یک ستون واحد 1NF را نقض میکند و به نیاز به یک جدول مرتبط جداگانه اشاره میکند.
فرم نرمال دوم (2NF): بدون وابستگیهای جزئی
Second Normal Form (فرم نرمال دوم) بهطور خاص برای جداول با یک کلید اصلی ترکیبی (کلیدی ساختهشده از چند ستون) اعمال میشود، و نیاز دارد هر ستون غیرکلیدی به کل کلید بستگی داشته باشد، نه فقط بخشی از آن.
2NF را نقض میکند:
| student_id | course_id | grade | course_name |
|------------|-----------|-------|--------------|
کلید اصلی: (student_id، course_id)
مسئله: course_name فقط به course_id بستگی دارد،
نه به کل کلید ترکیبی —
یک "وابستگی جزئی"
2NF را برآورده میکند (تقسیم به دو جدول):
enrollments: student_id، course_id، grade
courses: course_id، course_nameستون course_name برای هر دانشآموزی که در آن درس ثبتنام کرده بود تکرار میشد، که فضا را هدر میداد و یک ناهنجاری بهروزرسانی یکسان از نظر ساختار با مسئله ایمیل مشتری که پیشتر نشان داده شد ایجاد میکرد. جداکردن آن به جدول خودش، فقط کلیددهیشده با course_id، افزونگی را کاملاً حذف میکند.
فرم نرمال سوم (3NF): بدون وابستگیهای گذرا
Third Normal Form (فرم نرمال سوم) نیاز دارد ستونهای غیرکلیدی فقط به کلید اصلی بستگی داشته باشند، نه به سایر ستونهای غیرکلیدی — و آنچه Transitive Dependency (وابستگی گذرا) نامیده میشود را حذف میکند.
3NF را نقض میکند:
| employee_id | department_id | department_name |
|-------------|----------------|-------------------|
مسئله: department_name به department_id بستگی دارد،
که خودش یک ستون غیرکلیدی است —
یک وابستگی گذرا از میان department_id،
نه یک وابستگی مستقیم به employee_id
3NF را برآورده میکند (تقسیم به دو جدول):
employees: employee_id، department_id
departments: department_id، department_nameبدون این تقسیم، بهروزرسانی نام یک بخش نیازمند بهروزرسانی آن در هر ردیف هر کارمندی که به آن بخش تخصیص یافته خواهد بود — دقیقاً همان الگوی ناهنجاری بهروزرسانی که در سراسر این مقاله دیده شد، که اکنون با اطمینان از اینکه نام بخش دقیقاً در یک مکان زندگی میکند حل میشود.
فرم نرمال بویس-کاد (BCNF): یک اصلاح سختگیرانهتر
BCNF با نیاز به اینکه برای هر وابستگی معنادار بین ستونها، ستون در سمت تعیینکننده باید یک کلید کاندید باشد (یک ستون یا مجموعهای از ستونها که قادر به شناسایی یکتای یک ردیف هستند)، 3NF را سختتر میکند. بیشتر جداول 3NF از قبل BCNF را برآورده میکنند، اما جداول خاصی با کلیدهای کاندید همپوشان میتوانند 3NF را برآورده کنند در حالی که همچنان افزونگی ظریفی که BCNF میگیرد را شامل شوند.
یک جدول میتواند 3NF را برآورده کند اما همچنان
BCNF را نقض کند در مواردی شامل چند کلید کاندید همپوشان
— یک حالت لبهای نسبتاً نادر اما مهم که در آن
یک وابستگی تابعی وجود دارد که ستون تعیینکنندهاش
خودش یک کلید کاندید کامل نیستدر عمل، بیشتر طراحیهای دیتابیس دنیای واقعی در 3NF متوقف میشوند، چون نقضهای BCNF غیرمعمول هستند و افزونگی باقیماندهای که میگیرند معمولاً در مقایسه با ناهنجاریهایی که از قبل با رسیدن به 3NF حذف شدهاند جزئی است.
مبادله عملی: نرمالسازی در مقابل کارایی
نرمالسازی کامل افزونگی و ناهنجاریهایی که ایجاد میکند را حذف میکند، اما هزینهای دارد: داده بهشدت نرمالشده در سراسر بسیاری جدول کوچک تقسیم میشود، به این معنا که حتی کوئریهای ساده اغلب نیازمند چند JOIN، که پیشتر در این مجموعه بحث شد، برای بازآرایی یک تصویر کامل هستند، که میتواند بارهای کاری خواندن-سنگین را کند کند.
مثال مبادله denormalization:
یک طراحی کاملاً نرمالشده ممکن است نیازمند join کردن
5 جدول برای نمایش یک صفحه تأیید سفارش واحد باشد
یک طراحی عمداً denormalize-شده ممکن است مقدار کمی
داده (مانند نام یک مشتری) را مستقیماً در جدول
سفارشها تکرار کند، و برخی ریسک افزونگی را در ازای
خواندنهای سریعتر بپذیردDenormalization (غیرنرمالسازی) — عمداً معرفیمجدد برخی افزونگی پس از نرمالسازی — یک عمل مشروع و رایج برای بخشهای حساس-به-کارایی یک سیستم است، اما همیشه باید یک مبادله آگاهانه باشد که پس از درک ناهنجاریهایی که دوباره معرفی میشوند گرفته شده، نه یک میانبر گرفتهشده برای اجتناب از یادگیری نرمالسازی درست از ابتدا.
چرا درک قوانین نرمالسازی اهمیت دارد
نرمالسازی یک روششناسی دقیق و قابلبررسی برای گرفتن نقصهای طراحی که در غیر این صورت ممکن است فقط بهعنوان باگهای داده گیجکننده ماهها یا سالها پس از تولیدیشدن یک دیتابیس ظاهر شوند فراهم میکند. حتی در موقعیتهایی که denormalization عمدی در نهایت مبادله کارایی درستی است، درک دقیق اینکه کدام قانون نرمالسازی شل میشود، و دقیقاً کدام ریسک ناهنجاری عمداً پذیرفته میشود، چیزی است که یک مبادله مهندسی آگاهانه را از یک نقص طراحی تصادفی جدا میکند.